/**
 * *****************************************
 * Project: cone
 * File: RestfulServiceImpl.java
 * Creation Date: 1:58:34 PM
 * Creator: Ahmed Fawzy
 * *****************************************
 * Copyright © 2012 Devariance.
 */
package com.devariance.cone.rs.impl;

import java.util.List;

import javax.naming.OperationNotSupportedException;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.devariance.cone.Constants;
import com.devariance.cone.exception.InvalidResourceHandlerContextException;
import com.devariance.cone.handler.ResourceHandler;
import com.devariance.cone.handler.ResourceHandlerContext;
import com.devariance.cone.handler.exception.InternalResourceHandlerException;
import com.devariance.cone.handler.exception.InvalidResourceException;
import com.devariance.cone.handler.exception.InvalidResourceHandlerException;
import com.devariance.cone.handler.exception.ResourceCannotBeAcceptedException;
import com.devariance.cone.handler.exception.ResourceCannotBeUpdatedException;
import com.devariance.cone.handler.exception.ResourceNotFoundException;
import com.devariance.cone.logging.HasLogger;
import com.devariance.cone.resource.Resource;
import com.devariance.cone.rs.RestfulService;
import com.sun.jersey.api.view.Viewable;

/**
 * @author Ahmed Fawzy
 * 
 */
@Path("/")
public class RestfulServiceImpl implements HasLogger, RestfulService {

	private ResourceHandlerContext resourceHandlerContext = null;

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	/**
	 * @param resourceName
	 * @param identifier
	 * @return
	 */
	@DELETE
	@Produces({ MediaType.TEXT_HTML })
	@Path("{resourceName: [a-z]+(/[a-z]+)*}/{identifier: [0-9]+}")
	public Response deleteHtml(
			@PathParam("resourceName") final String resourceName,
			@PathParam("identifier") final String identifier) {

		if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
				: false) {
			this.getLogger()
					.debug("requested restful url: " + resourceName + ", identifier: " + identifier); //$NON-NLS-1$ //$NON-NLS-2$
		}

		ResourceHandler<? extends Resource> resourceHandler = null;

		if (this.resourceHandlerContext == null && this.getLogger() != null ? this
				.getLogger().isErrorEnabled() : false) {
			this.logger.error(
					"'resourceHandlerContext' property must not be null", //$NON-NLS-1$ 
					new InvalidResourceHandlerContextException(
							"null resourceHandlerContext reference")); //$NON-NLS-1$
			return Response.status(500)
					// Internal Server Error
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							500))).build();
		}

		try {
			resourceHandler = this.resourceHandlerContext
					.getResourceHandler(resourceName);
		} catch (final InvalidResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("no resource handler found for resource name: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(404)
					// Not Found
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							404))).build();
		}

		Long id = null;

		try {
			id = new Long(Long.parseLong(identifier));
		} catch (final NumberFormatException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger().debug(
						new StringBuilder()
								.append("invalid specified identifier: '") //$NON-NLS-1$
								.append(identifier).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(400)
					// Bad Request
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							400))).build();
		}

		try {
			resourceHandler.delete(id);
		} catch (final OperationNotSupportedException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder().append("this method call ") //$NON-NLS-1$
								.append("is not supported yet on ") //$NON-NLS-1$
								.append("the requested resource: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response
					.status(405)
					// Method Not Allowed
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							405)))
					.header("Allow", resourceHandler.getOptions()).build(); //$NON-NLS-1$
		} catch (final ResourceNotFoundException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("cannot find the requested resource: '") //$NON-NLS-1$
								.append(resourceName)
								.append("' with identifier: '") //$NON-NLS-1$
								.append(identifier).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(404)
					// Not Found
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							404))).build();
		} catch (final InternalResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isErrorEnabled()
					: false) {
				this.getLogger().error(
						"an internal server error has occurred", e); //$NON-NLS-1$
			}

			return Response.status(500)
					// Internal Server Error
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							500))).build();
		} catch (final InvalidResourceException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger().debug(
						new StringBuilder()
								.append("invalid resource specified") //$NON-NLS-1$
								.toString(), e);
			}

			return Response.status(400)
					// Bad Request
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							400))).build();
		} catch (final ResourceCannotBeUpdatedException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug("resource cannot be updated with the given instance", e); //$NON-NLS-1$
			}

			return Response.status(403)
					// Forbidden
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							403))).build();
		}

		return Response.status(200) // Ok
				.entity(new Viewable(resourceName, id)).build();
	}

	/**
	 * @param resourceName
	 * @param identifier
	 * @return
	 */
	@DELETE
	@Produces({ MediaType.APPLICATION_JSON })
	@Path("{resourceName: [a-z]+(/[a-z]+)*}/{identifier: [0-9]+}")
	public Response deleteJson(
			@PathParam("resourceName") final String resourceName,
			@PathParam("identifier") final String identifier) {

		if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
				: false) {
			this.getLogger()
					.debug("requested restful url: " + resourceName + ", identifier: " + identifier); //$NON-NLS-1$ //$NON-NLS-2$
		}

		ResourceHandler<? extends Resource> resourceHandler = null;

		if (this.resourceHandlerContext == null && this.getLogger() != null ? this
				.getLogger().isErrorEnabled() : false) {
			this.logger.error(
					"'resourceHandlerContext' property must not be null", //$NON-NLS-1$ 
					new InvalidResourceHandlerContextException(
							"null resourceHandlerContext reference")); //$NON-NLS-1$
			return Response.status(500)
			// Internal Server Error
					.entity(Constants.EMPTY_JSON_STRING).build();
		}

		try {
			resourceHandler = this.resourceHandlerContext
					.getResourceHandler(resourceName);
		} catch (final InvalidResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("no resource handler found for resource name: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(404)
			// Not Found
					.entity(Constants.EMPTY_JSON_STRING).build();
		}

		Long id = null;

		try {
			id = new Long(Long.parseLong(identifier));
		} catch (final NumberFormatException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger().debug(
						new StringBuilder()
								.append("invalid specified identifier: '") //$NON-NLS-1$
								.append(identifier).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(400)
			// Bad Request
					.entity(Constants.EMPTY_JSON_STRING).build();
		}

		try {
			resourceHandler.delete(id);
		} catch (final OperationNotSupportedException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder().append("this method call ") //$NON-NLS-1$
								.append("is not supported yet on ") //$NON-NLS-1$
								.append("the requested resource: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(405)
					// Method Not Allowed
					.entity(Constants.EMPTY_JSON_STRING)
					.header("Allow", resourceHandler.getOptions()).build(); //$NON-NLS-1$
		} catch (final ResourceNotFoundException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("cannot find the requested resource: '") //$NON-NLS-1$
								.append(resourceName)
								.append("' with identifier: '") //$NON-NLS-1$
								.append(identifier).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(404)
			// Not Found
					.entity(Constants.EMPTY_JSON_STRING).build();
		} catch (final InternalResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isErrorEnabled()
					: false) {
				this.getLogger().error(
						"an internal server error has occurred", e); //$NON-NLS-1$
			}

			return Response.status(500)
			// Internal Server Error
					.entity(Constants.EMPTY_JSON_STRING).build();
		} catch (final InvalidResourceException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger().debug(
						new StringBuilder()
								.append("invalid resource specified") //$NON-NLS-1$
								.toString(), e);
			}

			return Response.status(400)
			// Bad Request
					.entity(Constants.EMPTY_JSON_STRING).build();
		} catch (final ResourceCannotBeUpdatedException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug("resource cannot be updated with the given instance", e); //$NON-NLS-1$
			}

			return Response.status(403)
			// Forbidden
					.entity(Constants.EMPTY_JSON_STRING).build();
		}

		return Response.status(200) // Ok
				.entity(Constants.EMPTY_JSON_STRING).build();
	}

	/**
	 * @param resourceName
	 * @param identifier
	 * @return
	 */
	@DELETE
	@Produces({ MediaType.APPLICATION_XML })
	@Path("{resourceName: [a-z]+(/[a-z]+)*}/{identifier: [0-9]+}")
	public Response deleteXml(
			@PathParam("resourceName") final String resourceName,
			@PathParam("identifier") final String identifier) {

		if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
				: false) {
			this.getLogger()
					.debug("requested restful url: " + resourceName + ", identifier: " + identifier); //$NON-NLS-1$ //$NON-NLS-2$
		}

		ResourceHandler<? extends Resource> resourceHandler = null;

		if (this.resourceHandlerContext == null && this.getLogger() != null ? this
				.getLogger().isErrorEnabled() : false) {
			this.logger.error(
					"'resourceHandlerContext' property must not be null", //$NON-NLS-1$ 
					new InvalidResourceHandlerContextException(
							"null resourceHandlerContext reference")); //$NON-NLS-1$
			return Response.status(500)
			// Internal Server Error
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		}

		try {
			resourceHandler = this.resourceHandlerContext
					.getResourceHandler(resourceName);
		} catch (final InvalidResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("no resource handler found for resource name: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(404)
			// Not Found
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		}

		Long id = null;

		try {
			id = new Long(Long.parseLong(identifier));
		} catch (final NumberFormatException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger().debug(
						new StringBuilder()
								.append("invalid specified identifier: '") //$NON-NLS-1$
								.append(identifier).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(400)
			// Bad Request
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		}

		try {
			resourceHandler.delete(id);
		} catch (final OperationNotSupportedException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder().append("this method call ") //$NON-NLS-1$
								.append("is not supported yet on ") //$NON-NLS-1$
								.append("the requested resource: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(405)
					// Method Not Allowed
					.entity(Constants.EMPTY_XML_DOCUMENT)
					.header("Allow", resourceHandler.getOptions()).build(); //$NON-NLS-1$
		} catch (final ResourceNotFoundException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("cannot find the requested resource: '") //$NON-NLS-1$
								.append(resourceName)
								.append("' with identifier: '") //$NON-NLS-1$
								.append(identifier).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(404)
			// Not Found
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		} catch (final InternalResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isErrorEnabled()
					: false) {
				this.getLogger().error(
						"an internal server error has occurred", e); //$NON-NLS-1$
			}

			return Response.status(500)
			// Internal Server Error
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		} catch (final InvalidResourceException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger().debug(
						new StringBuilder()
								.append("invalid resource specified") //$NON-NLS-1$
								.toString(), e);
			}

			return Response.status(400)
			// Bad Request
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		} catch (final ResourceCannotBeUpdatedException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug("resource cannot be updated with the given instance", e); //$NON-NLS-1$
			}

			return Response.status(403)
			// Forbidden
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		}

		return Response.status(200) // Ok
				.entity(Constants.EMPTY_XML_DOCUMENT).build();
	}

	/**
	 * @return
	 */
	@GET
	@Produces(MediaType.TEXT_HTML)
	public Response getDefaultHtml() {
		return Response.ok(new Viewable(Constants.DEFAULT_PAGE_NAME)).build();
	}

	/**
	 * @param resourceName
	 * @param identifier
	 * @return
	 */
	@GET
	@Path("{resourceName: [a-z]+(/[a-z]+)*}/{identifier: [0-9]+}")
	@Produces({ MediaType.TEXT_HTML })
	public Response getHtml(
			@PathParam("resourceName") final String resourceName,
			@PathParam("identifier") final String identifier) {

		if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
				: false) {
			this.getLogger()
					.debug("requested restful url: " + resourceName + ", identifier: " + identifier); //$NON-NLS-1$ //$NON-NLS-2$
		}

		ResourceHandler<? extends Resource> resourceHandler = null;

		if (this.resourceHandlerContext == null && this.logger.isErrorEnabled()) {
			this.logger.error(
					"'resourceHandlerContext' property must not be null", //$NON-NLS-1$ 
					new InvalidResourceHandlerContextException(
							"null resourceHandlerContext reference")); //$NON-NLS-1$
			return Response.status(500)
					// Internal Server Error
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							500))).build();
		}

		try {
			resourceHandler = this.resourceHandlerContext
					.getResourceHandler(resourceName);
		} catch (final InvalidResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("no resource found with name: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(404)
					// Not Found
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							404))).build();
		}

		Long id = null;

		try {
			id = new Long(Long.parseLong(identifier));
		} catch (final NumberFormatException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger().debug(
						new StringBuilder()
								.append("invalid specified identifier: '") //$NON-NLS-1$
								.append(identifier).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(400)
					// Bad Request
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							400))).build();
		}

		Resource resource = null;

		try {
			resource = resourceHandler.get(id);
		} catch (final OperationNotSupportedException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder().append("this method call ") //$NON-NLS-1$
								.append("is not supported yet on ") //$NON-NLS-1$
								.append("the requested resource: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response
					.status(405)
					// Method Not Allowed
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							405)))
					.header("Allow", resourceHandler.getOptions()).build(); //$NON-NLS-1$
		} catch (final ResourceNotFoundException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("cannot find the requested resource: '") //$NON-NLS-1$
								.append(resourceName)
								.append("' with identifier: '") //$NON-NLS-1$
								.append(identifier).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(404)
					// Not Found
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							404))).build();
		} catch (final InternalResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isErrorEnabled()
					: false) {
				this.getLogger().error(
						"an internal server error has occurred", e); //$NON-NLS-1$
			}

			return Response.status(500)
					// Internal Server Error
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							500))).build();
		}

		return Response.status(200) // Ok
				.entity(new Viewable(resourceName, resource)).build();
	}

	/**
	 * @param resourceName
	 * @param identifier
	 * @return
	 */
	@GET
	@Path("{resourceName: [a-z]+(/[a-z]+)*}/{identifier: [0-9]+}")
	@Produces({ MediaType.APPLICATION_JSON })
	public Response getJson(
			@PathParam("resourceName") final String resourceName,
			@PathParam("identifier") final String identifier) {

		if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
				: false) {
			this.getLogger()
					.debug("requested restful url: " + resourceName + ", identifier: " + identifier); //$NON-NLS-1$ //$NON-NLS-2$
		}

		ResourceHandler<? extends Resource> resourceHandler = null;

		if (this.resourceHandlerContext == null && this.logger.isErrorEnabled()) {
			this.logger.error(
					"'resourceHandlerContext' property must not be null", //$NON-NLS-1$ 
					new InvalidResourceHandlerContextException(
							"null resourceHandlerContext reference")); //$NON-NLS-1$
			return Response.status(500) // Internal Server Error
					.entity(Constants.EMPTY_JSON_STRING).build();
		}

		try {
			resourceHandler = this.resourceHandlerContext
					.getResourceHandler(resourceName);
		} catch (final InvalidResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("no resource found with name: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(404) // Not Found
					.entity(Constants.EMPTY_JSON_STRING).build();
		}

		Long id = null;

		try {
			id = new Long(Long.parseLong(identifier));
		} catch (final NumberFormatException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger().debug(
						new StringBuilder()
								.append("invalid specified identifier: '") //$NON-NLS-1$
								.append(identifier).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(400) // Bad Request
					.entity(Constants.EMPTY_JSON_STRING).build();
		}

		Resource resource = null;

		try {
			resource = resourceHandler.get(id);
		} catch (final OperationNotSupportedException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder().append("this method call ") //$NON-NLS-1$
								.append("is not supported yet on ") //$NON-NLS-1$
								.append("the requested resource: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(405)
					// Method Not Allowed
					.entity(Constants.EMPTY_JSON_STRING)
					.header("Allow", resourceHandler.getOptions()).build(); //$NON-NLS-1$
		} catch (final ResourceNotFoundException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("cannot find the requested resource: '") //$NON-NLS-1$
								.append(resourceName)
								.append("' with identifier: '") //$NON-NLS-1$
								.append(identifier).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(404) // Not Found
					.entity(Constants.EMPTY_JSON_STRING).build();
		} catch (final InternalResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isErrorEnabled()
					: false) {
				this.getLogger().error(
						"an internal server error has occurred", e); //$NON-NLS-1$
			}

			return Response.status(500) // Internal Server Error
					.entity(Constants.EMPTY_JSON_STRING).build();
		}

		return Response.status(200) // Ok
				.entity(resource).build();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.devariance.cone.logging.HasLogger#getLogger()
	 */
	@Override
	public Logger getLogger() {
		return this.logger;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.devariance.cone.rs.RestfulService#getResourceHandlerContext()
	 */
	@Override
	public ResourceHandlerContext getResourceHandlerContext() {
		return this.resourceHandlerContext;
	}

	/**
	 * @param resourceName
	 * @param identifier
	 * @return
	 */
	@GET
	@Path("{resourceName: [a-z]+(/[a-z]+)*}/{identifier: [0-9]+}")
	@Produces({ MediaType.APPLICATION_XML })
	public Response getXml(
			@PathParam("resourceName") final String resourceName,
			@PathParam("identifier") final String identifier) {

		if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
				: false) {
			this.getLogger()
					.debug("requested restful url: " + resourceName + ", identifier: " + identifier); //$NON-NLS-1$ //$NON-NLS-2$
		}

		ResourceHandler<? extends Resource> resourceHandler = null;

		if (this.resourceHandlerContext == null && this.logger.isErrorEnabled()) {
			this.logger.error(
					"'resourceHandlerContext' property must not be null", //$NON-NLS-1$ 
					new InvalidResourceHandlerContextException(
							"null resourceHandlerContext reference")); //$NON-NLS-1$
			return Response.status(500) // Internal Server Error
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		}

		try {
			resourceHandler = this.resourceHandlerContext
					.getResourceHandler(resourceName);
		} catch (final InvalidResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("no resource found with name: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(404) // Not Found
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		}

		Long id = null;

		try {
			id = new Long(Long.parseLong(identifier));
		} catch (final NumberFormatException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger().debug(
						new StringBuilder()
								.append("invalid specified identifier: '") //$NON-NLS-1$
								.append(identifier).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(400) // Bad Request
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		}

		Resource resource = null;

		try {
			resource = resourceHandler.get(id);
		} catch (final OperationNotSupportedException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("get xml method call ") //$NON-NLS-1$
								.append("is not supported yet on ") //$NON-NLS-1$
								.append("the requested resource: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(405)
					// Method Not Allowed
					.entity(Constants.EMPTY_XML_DOCUMENT)
					.header("Allow", resourceHandler.getOptions()).build(); //$NON-NLS-1$
		} catch (final ResourceNotFoundException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("cannot find the requested resource: '") //$NON-NLS-1$
								.append(resourceName)
								.append("' with identifier: '") //$NON-NLS-1$
								.append(identifier).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(404) // Not Found
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		} catch (final InternalResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isErrorEnabled()
					: false) {
				this.getLogger().error(
						"an internal server error has occurred", e); //$NON-NLS-1$
			}

			return Response.status(500) // Internal Server Error
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		}

		return Response.status(200) // Ok
				.entity(resource).build();
	}

	/**
	 * @param resourceName
	 * @return
	 */
	@GET
	@Path("{resourceName: [a-z]+(/[a-z]+)*}")
	@Produces({ MediaType.TEXT_HTML })
	public Response listHtml(
			@PathParam("resourceName") final String resourceName) {

		if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
				: false) {
			this.getLogger().debug("requested restful url: " + resourceName); //$NON-NLS-1$
		}

		ResourceHandler<? extends Resource> resourceHandler = null;

		if (this.resourceHandlerContext == null && this.logger.isErrorEnabled()) {
			this.logger.error(
					"'resourceHandlerContext' property must not be null", //$NON-NLS-1$ 
					new InvalidResourceHandlerContextException(
							"null resourceHandlerContext reference")); //$NON-NLS-1$
			return Response.status(500)
					// Internal Server Error
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							500))).build();
		}

		try {
			resourceHandler = this.resourceHandlerContext
					.getResourceHandler(resourceName);
		} catch (final InvalidResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("no resource found with name: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(404)
					// Not Found
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							404))).build();
		}

		List<? extends Resource> resource = null;

		try {
			resource = resourceHandler.get(null, null);
		} catch (final OperationNotSupportedException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder().append("this method call ") //$NON-NLS-1$
								.append("is not supported yet on ") //$NON-NLS-1$
								.append("the requested resource: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response
					.status(405)
					// Method Not Allowed
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							405)))
					.header("Allow", resourceHandler.getOptions()).build(); //$NON-NLS-1$
		} catch (final InternalResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isErrorEnabled()
					: false) {
				this.getLogger().error(
						"an internal server error has occurred", e); //$NON-NLS-1$
			}

			return Response.status(500)
					// Internal Server Error
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							500))).build();
		}

		return Response.status(200) // Ok
				.entity(new Viewable(resourceName, resource)).build();
	}

	/**
	 * @param resourceName
	 * @return
	 */
	@GET
	@Path("{resourceName: [a-z]+(/[a-z]+)*}")
	@Produces({ MediaType.APPLICATION_JSON })
	public Response listJson(
			@PathParam("resourceName") final String resourceName) {

		if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
				: false) {
			this.getLogger().debug("requested restful url: " + resourceName); //$NON-NLS-1$
		}

		ResourceHandler<? extends Resource> resourceHandler = null;

		if (this.resourceHandlerContext == null && this.logger.isErrorEnabled()) {
			this.logger.error(
					"'resourceHandlerContext' property must not be null", //$NON-NLS-1$ 
					new InvalidResourceHandlerContextException(
							"null resourceHandlerContext reference")); //$NON-NLS-1$
			return Response.status(500) // Internal Server Error
					.entity(Constants.EMPTY_JSON_STRING).build();
		}

		try {
			resourceHandler = this.resourceHandlerContext
					.getResourceHandler(resourceName);
		} catch (final InvalidResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("no resource found with name: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(404) // Not Found
					.entity(Constants.EMPTY_JSON_STRING).build();
		}

		List<? extends Resource> resource = null;

		try {
			resource = resourceHandler.get(null, null);
		} catch (final OperationNotSupportedException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder().append("this method call ") //$NON-NLS-1$
								.append("is not supported yet on ") //$NON-NLS-1$
								.append("the requested resource: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(405)
					// Method Not Allowed
					.entity(Constants.EMPTY_JSON_STRING)
					.header("Allow", resourceHandler.getOptions()).build(); //$NON-NLS-1$
		} catch (final InternalResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isErrorEnabled()
					: false) {
				this.getLogger().error(
						"an internal server error has occurred", e); //$NON-NLS-1$
			}

			return Response.status(500) // Internal Server Error
					.entity(Constants.EMPTY_JSON_STRING).build();
		}

		return Response.status(200) // Ok
				.entity(resource).build();
	}

	/**
	 * @param resourceName
	 * @return
	 */
	@GET
	@Path("{resourceName: [a-z]+(/[a-z]+)*}")
	@Produces({ MediaType.APPLICATION_XML })
	public Response listXml(@PathParam("resourceName") final String resourceName) {

		if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
				: false) {
			this.getLogger().debug("requested restful url: " + resourceName); //$NON-NLS-1$
		}

		ResourceHandler<? extends Resource> resourceHandler = null;

		if (this.resourceHandlerContext == null && this.logger.isErrorEnabled()) {
			this.logger.error(
					"'resourceHandlerContext' property must not be null", //$NON-NLS-1$ 
					new InvalidResourceHandlerContextException(
							"null resourceHandlerContext reference")); //$NON-NLS-1$
			return Response.status(500) // Internal Server Error
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		}

		try {
			resourceHandler = this.resourceHandlerContext
					.getResourceHandler(resourceName);
		} catch (final InvalidResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("no resource found with name: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(404) // Not Found
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		}

		List<? extends Resource> resource = null;

		try {
			resource = resourceHandler.get(null, null);
		} catch (final OperationNotSupportedException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder().append("this method call ") //$NON-NLS-1$
								.append("is not supported yet on ") //$NON-NLS-1$
								.append("the requested resource: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(405)
					// Method Not Allowed
					.entity(Constants.EMPTY_XML_DOCUMENT)
					.header("Allow", resourceHandler.getOptions()).build(); //$NON-NLS-1$
		} catch (final InternalResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isErrorEnabled()
					: false) {
				this.getLogger().error(
						"an internal server error has occurred", e); //$NON-NLS-1$
			}

			return Response.status(500) // Internal Server Error
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		}

		return Response.status(200) // Ok
				.entity(resource).build();
	}

	/**
	 * @param uriInfo
	 * @param resourceName
	 * @param formParams
	 * @return
	 */
	@POST
	@Path("{resourceName: [a-z]+(/[a-z]+)*}")
	@Produces({ MediaType.TEXT_HTML })
	@Consumes({ MediaType.APPLICATION_FORM_URLENCODED })
	public Response postHtml(@Context final UriInfo uriInfo,
			@PathParam("resourceName") final String resourceName,
			final MultivaluedMap<String, String> formParams) {

		if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
				: false) {
			this.getLogger().debug("requested restful url: " + resourceName); //$NON-NLS-1$
		}

		ResourceHandler<? extends Resource> resourceHandler = null;

		if (this.resourceHandlerContext == null && this.logger.isErrorEnabled()) {
			this.logger.error(
					"'resourceHandlerContext' property must not be null", //$NON-NLS-1$ 
					new InvalidResourceHandlerContextException(
							"null resourceHandlerContext reference")); //$NON-NLS-1$
			return Response.status(500)
					// Internal Server Error
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							500))).build();
		}

		try {
			resourceHandler = this.resourceHandlerContext
					.getResourceHandler(resourceName);
		} catch (final InvalidResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("no resource handler found for resource name: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(404)
					// Not Found
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							404))).build();
		}

		final Resource resource = resourceHandler.createResource(formParams);

		if (resource == null) {
			this.logger.error(new StringBuilder("resource handler '") //$NON-NLS-1$
					.append(resourceName)
					.append("' cannot create a resource instance") //$NON-NLS-1$
					.toString());
			return Response.status(500)
					// Internal Server Error
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							500))).build();
		}

		Long id = null;

		try {
			id = resourceHandler.post(resource);
		} catch (final OperationNotSupportedException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("get xml method call ") //$NON-NLS-1$
								.append("is not supported yet on ") //$NON-NLS-1$
								.append("the requested resource: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response
					.status(405)
					// Method Not Allowed
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							405)))
					.header("Allow", resourceHandler.getOptions()).build(); //$NON-NLS-1$
		} catch (final ResourceNotFoundException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("cannot find the requested resource: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(404)
					// Not Found
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							404))).build();
		} catch (final InternalResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isErrorEnabled()
					: false) {
				this.getLogger().error(
						"an internal server error has occurred", e); //$NON-NLS-1$
			}

			return Response.status(500)
					// Internal Server Error
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							500))).build();
		} catch (final InvalidResourceException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger().debug(
						new StringBuilder()
								.append("invalid resource specified") //$NON-NLS-1$
								.toString(), e);
			}

			return Response.status(400)
					// Bad Request
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							400))).build();
		} catch (final ResourceCannotBeAcceptedException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger().debug("resource cannot be accepted", e); //$NON-NLS-1$
			}

			return Response.status(403)
					// Forbidden
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							403))).build();
		}

		if (id == null) {
			if (this.getLogger() != null ? this.getLogger().isErrorEnabled()
					: false) {
				this.getLogger()
						.error(new StringBuilder(
								"null value returned from POST operation for resource: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString()); //$NON-NLS-1$
			}

			return Response.status(500)
					// Internal Server Error
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							500))).build();
		}

		return Response.status(201)
		// Created
				.entity(new Viewable(resourceName, id)).build();
	}

	/**
	 * @param uriInfo
	 * @param resourceName
	 * @param formParams
	 * @return
	 */
	@POST
	@Path("{resourceName: [a-z]+(/[a-z]+)*}")
	@Produces({ MediaType.APPLICATION_JSON })
	@Consumes({ MediaType.APPLICATION_FORM_URLENCODED })
	public Response postJson(@Context final UriInfo uriInfo,
			@PathParam("resourceName") final String resourceName,
			final MultivaluedMap<String, String> formParams) {

		if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
				: false) {
			this.getLogger().debug("requested restful url: " + resourceName); //$NON-NLS-1$
		}

		ResourceHandler<? extends Resource> resourceHandler = null;

		if (this.resourceHandlerContext == null && this.logger.isErrorEnabled()) {
			this.logger.error(
					"'resourceHandlerContext' property must not be null", //$NON-NLS-1$ 
					new InvalidResourceHandlerContextException(
							"null resourceHandlerContext reference")); //$NON-NLS-1$
			return Response.status(500) // Internal Server Error
					.entity(Constants.EMPTY_JSON_STRING).build();
		}

		try {
			resourceHandler = this.resourceHandlerContext
					.getResourceHandler(resourceName);
		} catch (final InvalidResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("no resource handler found for resource name: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(404) // Not Found
					.entity(Constants.EMPTY_JSON_STRING).build();
		}

		final Resource resource = resourceHandler.createResource(formParams);

		if (resource == null) {
			this.logger.error(new StringBuilder("resource handler '") //$NON-NLS-1$
					.append(resourceName)
					.append("' cannot create a resource instance") //$NON-NLS-1$
					.toString());
			return Response.status(500) // Internal Server Error
					.entity(Constants.EMPTY_JSON_STRING).build();
		}

		Long id = null;

		try {
			id = resourceHandler.post(resource);
		} catch (final OperationNotSupportedException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("get xml method call ") //$NON-NLS-1$
								.append("is not supported yet on ") //$NON-NLS-1$
								.append("the requested resource: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(405)
					// Method Not Allowed
					.entity(Constants.EMPTY_JSON_STRING)
					.header("Allow", resourceHandler.getOptions()).build(); //$NON-NLS-1$
		} catch (final ResourceNotFoundException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("cannot find the requested resource: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(404) // Not Found
					.entity(Constants.EMPTY_JSON_STRING).build();
		} catch (final InternalResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isErrorEnabled()
					: false) {
				this.getLogger().error(
						"an internal server error has occurred", e); //$NON-NLS-1$
			}

			return Response.status(500) // Internal Server Error
					.entity(Constants.EMPTY_JSON_STRING).build();
		} catch (final InvalidResourceException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger().debug(
						new StringBuilder()
								.append("invalid resource specified") //$NON-NLS-1$
								.toString(), e);
			}

			return Response.status(400) // Bad Request
					.entity(Constants.EMPTY_JSON_STRING).build();
		} catch (final ResourceCannotBeAcceptedException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger().debug("resource cannot be accepted", e); //$NON-NLS-1$
			}

			return Response.status(403) // Forbidden
					.entity(Constants.EMPTY_JSON_STRING).build();
		}

		if (id == null) {
			if (this.getLogger() != null ? this.getLogger().isErrorEnabled()
					: false) {
				this.getLogger()
						.error(new StringBuilder(
								"null value returned from POST operation for resource: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString()); //$NON-NLS-1$
			}

			return Response.status(500) // Internal Server Error
					.entity(Constants.EMPTY_JSON_STRING).build();
		}

		return Response
				.status(201)
				// Created
				.entity(uriInfo.getAbsolutePathBuilder().path(id.toString())
						.build().toString()).build();
	}

	/**
	 * @param uriInfo
	 * @param resourceName
	 * @param formParams
	 * @return
	 */
	@POST
	@Path("{resourceName: [a-z]+(/[a-z]+)*}")
	@Produces({ MediaType.APPLICATION_XML })
	@Consumes({ MediaType.APPLICATION_FORM_URLENCODED })
	public Response postXml(@Context final UriInfo uriInfo,
			@PathParam("resourceName") final String resourceName,
			final MultivaluedMap<String, String> formParams) {

		if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
				: false) {
			this.getLogger().debug("requested restful url: " + resourceName); //$NON-NLS-1$
		}

		ResourceHandler<? extends Resource> resourceHandler = null;

		if (this.resourceHandlerContext == null && this.logger.isErrorEnabled()) {
			this.logger.error(
					"'resourceHandlerContext' property must not be null", //$NON-NLS-1$ 
					new InvalidResourceHandlerContextException(
							"null resourceHandlerContext reference")); //$NON-NLS-1$
			return Response.status(500) // Internal Server Error
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		}

		try {
			resourceHandler = this.resourceHandlerContext
					.getResourceHandler(resourceName);
		} catch (final InvalidResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("no resource handler found for resource name: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(404) // Not Found
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		}

		final Resource resource = resourceHandler.createResource(formParams);

		if (resource == null) {
			this.logger.error(new StringBuilder("resource handler '") //$NON-NLS-1$
					.append(resourceName)
					.append("' cannot create a resource instance") //$NON-NLS-1$
					.toString());
			return Response.status(500) // Internal Server Error
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		}

		Long id = null;

		try {
			id = resourceHandler.post(resource);
		} catch (final OperationNotSupportedException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("get xml method call ") //$NON-NLS-1$
								.append("is not supported yet on ") //$NON-NLS-1$
								.append("the requested resource: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(405)
					// Method Not Allowed
					.entity(Constants.EMPTY_XML_DOCUMENT)
					.header("Allow", resourceHandler.getOptions()).build(); //$NON-NLS-1$
		} catch (final ResourceNotFoundException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("cannot find the requested resource: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(404) // Not Found
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		} catch (final InternalResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isErrorEnabled()
					: false) {
				this.getLogger().error(
						"an internal server error has occurred", e); //$NON-NLS-1$
			}

			return Response.status(500) // Internal Server Error
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		} catch (final InvalidResourceException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger().debug(
						new StringBuilder()
								.append("invalid resource specified") //$NON-NLS-1$
								.toString(), e);
			}

			return Response.status(400) // Bad Request
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		} catch (final ResourceCannotBeAcceptedException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger().debug("resource cannot be accepted", e); //$NON-NLS-1$
			}

			return Response.status(403) // Forbidden
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		}

		if (id == null) {
			if (this.getLogger() != null ? this.getLogger().isErrorEnabled()
					: false) {
				this.getLogger()
						.error(new StringBuilder(
								"null value returned from POST operation for resource: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString()); //$NON-NLS-1$
			}

			return Response.status(500) // Internal Server Error
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		}

		return Response
				.status(201)
				// Created
				.entity(uriInfo.getAbsolutePathBuilder().path(id.toString())
						.build().toString()).build();
	}

	/**
	 * @param uriInfo
	 * @param resourceName
	 * @param identifier
	 * @param formParams
	 * @return
	 */
	@PUT
	@Path("{resourceName: [a-z]+(/[a-z]+)*}")
	@Produces({ MediaType.TEXT_HTML })
	@Consumes({ MediaType.APPLICATION_FORM_URLENCODED })
	public Response putHtml(@Context final UriInfo uriInfo,
			@PathParam("resourceName") final String resourceName,
			@PathParam("identifier") final String identifier,
			final MultivaluedMap<String, String> formParams) {

		if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
				: false) {
			this.getLogger().debug("requested restful url: " + resourceName); //$NON-NLS-1$
		}

		ResourceHandler<? extends Resource> resourceHandler = null;

		if (this.resourceHandlerContext == null && this.logger.isErrorEnabled()) {
			this.logger.error(
					"'resourceHandlerContext' property must not be null", //$NON-NLS-1$ 
					new InvalidResourceHandlerContextException(
							"null resourceHandlerContext reference")); //$NON-NLS-1$
			return Response.status(500)
					// Internal Server Error
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							500))).build();
		}

		try {
			resourceHandler = this.resourceHandlerContext
					.getResourceHandler(resourceName);
		} catch (final InvalidResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("no resource handler found for resource name: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(404)
					// Not Found
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							404))).build();
		}

		final Resource resource = resourceHandler.createResource(formParams);

		if (resource == null) {
			this.logger.error(new StringBuilder("resource handler '") //$NON-NLS-1$
					.append(resourceName)
					.append("' cannot create a resource instance") //$NON-NLS-1$
					.toString());
			return Response.status(500)
					// Internal Server Error
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							500))).build();
		}

		Long id = null;

		try {
			id = new Long(Long.parseLong(identifier));
		} catch (final NumberFormatException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger().debug(
						new StringBuilder()
								.append("invalid specified identifier: '") //$NON-NLS-1$
								.append(identifier).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(400)
					// Bad Request
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							400))).build();
		}

		resource.setIdentifier(id);

		try {
			resourceHandler.put(resource);
		} catch (final OperationNotSupportedException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("get xml method call ") //$NON-NLS-1$
								.append("is not supported yet on ") //$NON-NLS-1$
								.append("the requested resource: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response
					.status(405)
					// Method Not Allowed
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							405)))
					.header("Allow", resourceHandler.getOptions()).build(); //$NON-NLS-1$
		} catch (final ResourceNotFoundException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("cannot find the requested resource: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(404)
					// Not Found
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							404))).build();
		} catch (final InternalResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isErrorEnabled()
					: false) {
				this.getLogger().error(
						"an internal server error has occurred", e); //$NON-NLS-1$
			}

			return Response.status(500)
					// Internal Server Error
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							500))).build();
		} catch (final InvalidResourceException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger().debug(
						new StringBuilder()
								.append("invalid resource specified") //$NON-NLS-1$
								.toString(), e);
			}

			return Response.status(400)
					// Bad Request
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							400))).build();
		} catch (final ResourceCannotBeUpdatedException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger().debug("resource cannot be accepted", e); //$NON-NLS-1$
			}

			return Response.status(403)
					// Forbidden
					.entity(new Viewable(Constants.ERROR_PAGE_NAME, new Long(
							403))).build();
		}

		return Response.status(200)
		// Ok
				.entity(new Viewable(resourceName, id)).build();
	}

	/**
	 * @param uriInfo
	 * @param resourceName
	 * @param identifier
	 * @param formParams
	 * @return
	 */
	@PUT
	@Path("{resourceName: [a-z]+(/[a-z]+)*}")
	@Produces({ MediaType.APPLICATION_JSON })
	@Consumes({ MediaType.APPLICATION_FORM_URLENCODED })
	public Response putJson(@Context final UriInfo uriInfo,
			@PathParam("resourceName") final String resourceName,
			@PathParam("identifier") final String identifier,
			final MultivaluedMap<String, String> formParams) {

		if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
				: false) {
			this.getLogger().debug("requested restful url: " + resourceName); //$NON-NLS-1$
		}

		ResourceHandler<? extends Resource> resourceHandler = null;

		if (this.resourceHandlerContext == null && this.logger.isErrorEnabled()) {
			this.logger.error(
					"'resourceHandlerContext' property must not be null", //$NON-NLS-1$ 
					new InvalidResourceHandlerContextException(
							"null resourceHandlerContext reference")); //$NON-NLS-1$
			return Response.status(500) // Internal Server Error
					.entity(Constants.EMPTY_JSON_STRING).build();
		}

		try {
			resourceHandler = this.resourceHandlerContext
					.getResourceHandler(resourceName);
		} catch (final InvalidResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("no resource handler found for resource name: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(404) // Not Found
					.entity(Constants.EMPTY_JSON_STRING).build();
		}

		final Resource resource = resourceHandler.createResource(formParams);

		if (resource == null) {
			this.logger.error(new StringBuilder("resource handler '") //$NON-NLS-1$
					.append(resourceName)
					.append("' cannot create a resource instance") //$NON-NLS-1$
					.toString());
			return Response.status(500) // Internal Server Error
					.entity(Constants.EMPTY_JSON_STRING).build();
		}

		Long id = null;

		try {
			id = new Long(Long.parseLong(identifier));
		} catch (final NumberFormatException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger().debug(
						new StringBuilder()
								.append("invalid specified identifier: '") //$NON-NLS-1$
								.append(identifier).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(400) // Bad Request
					.entity(Constants.EMPTY_JSON_STRING).build();
		}

		resource.setIdentifier(id);

		try {
			resourceHandler.put(resource);
		} catch (final OperationNotSupportedException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("get xml method call ") //$NON-NLS-1$
								.append("is not supported yet on ") //$NON-NLS-1$
								.append("the requested resource: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(405)
					// Method Not Allowed
					.entity(Constants.EMPTY_JSON_STRING)
					.header("Allow", resourceHandler.getOptions()).build(); //$NON-NLS-1$
		} catch (final ResourceNotFoundException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("cannot find the requested resource: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(404) // Not Found
					.entity(Constants.EMPTY_JSON_STRING).build();
		} catch (final InternalResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isErrorEnabled()
					: false) {
				this.getLogger().error(
						"an internal server error has occurred", e); //$NON-NLS-1$
			}

			return Response.status(500) // Internal Server Error
					.entity(Constants.EMPTY_JSON_STRING).build();
		} catch (final InvalidResourceException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger().debug(
						new StringBuilder()
								.append("invalid resource specified") //$NON-NLS-1$
								.toString(), e);
			}

			return Response.status(400) // Bad Request
					.entity(Constants.EMPTY_JSON_STRING).build();
		} catch (final ResourceCannotBeUpdatedException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger().debug("resource cannot be accepted", e); //$NON-NLS-1$
			}

			return Response.status(403) // Forbidden
					.entity(Constants.EMPTY_JSON_STRING).build();
		}

		return Response.status(200)
				// Ok
				.entity(uriInfo.getAbsolutePathBuilder().build().toString())
				.build();
	}

	/**
	 * @param uriInfo
	 * @param resourceName
	 * @param identifier
	 * @param formParams
	 * @return
	 */
	@PUT
	@Path("{resourceName: [a-z]+(/[a-z]+)*}")
	@Produces({ MediaType.APPLICATION_XML })
	@Consumes({ MediaType.APPLICATION_FORM_URLENCODED })
	public Response putXml(@Context final UriInfo uriInfo,
			@PathParam("resourceName") final String resourceName,
			@PathParam("identifier") final String identifier,
			final MultivaluedMap<String, String> formParams) {

		if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
				: false) {
			this.getLogger().debug("requested restful url: " + resourceName); //$NON-NLS-1$
		}

		ResourceHandler<? extends Resource> resourceHandler = null;

		if (this.resourceHandlerContext == null && this.logger.isErrorEnabled()) {
			this.logger.error(
					"'resourceHandlerContext' property must not be null", //$NON-NLS-1$ 
					new InvalidResourceHandlerContextException(
							"null resourceHandlerContext reference")); //$NON-NLS-1$
			return Response.status(500) // Internal Server Error
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		}

		try {
			resourceHandler = this.resourceHandlerContext
					.getResourceHandler(resourceName);
		} catch (final InvalidResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("no resource handler found for resource name: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(404) // Not Found
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		}

		final Resource resource = resourceHandler.createResource(formParams);

		if (resource == null) {
			this.logger.error(new StringBuilder("resource handler '") //$NON-NLS-1$
					.append(resourceName)
					.append("' cannot create a resource instance") //$NON-NLS-1$
					.toString());
			return Response.status(500) // Internal Server Error
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		}

		Long id = null;

		try {
			id = new Long(Long.parseLong(identifier));
		} catch (final NumberFormatException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger().debug(
						new StringBuilder()
								.append("invalid specified identifier: '") //$NON-NLS-1$
								.append(identifier).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(400) // Bad Request
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		}

		resource.setIdentifier(id);

		try {
			resourceHandler.put(resource);
		} catch (final OperationNotSupportedException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("get xml method call ") //$NON-NLS-1$
								.append("is not supported yet on ") //$NON-NLS-1$
								.append("the requested resource: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(405)
					// Method Not Allowed
					.entity(Constants.EMPTY_XML_DOCUMENT)
					.header("Allow", resourceHandler.getOptions()).build(); //$NON-NLS-1$
		} catch (final ResourceNotFoundException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger()
						.debug(new StringBuilder()
								.append("cannot find the requested resource: '") //$NON-NLS-1$
								.append(resourceName).append("'").toString(), e); //$NON-NLS-1$
			}

			return Response.status(404) // Not Found
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		} catch (final InternalResourceHandlerException e) {
			if (this.getLogger() != null ? this.getLogger().isErrorEnabled()
					: false) {
				this.getLogger().error(
						"an internal server error has occurred", e); //$NON-NLS-1$
			}

			return Response.status(500) // Internal Server Error
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		} catch (final InvalidResourceException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger().debug(
						new StringBuilder()
								.append("invalid resource specified") //$NON-NLS-1$
								.toString(), e);
			}

			return Response.status(400) // Bad Request
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		} catch (final ResourceCannotBeUpdatedException e) {
			if (this.getLogger() != null ? this.getLogger().isDebugEnabled()
					: false) {
				this.getLogger().debug("resource cannot be accepted", e); //$NON-NLS-1$
			}

			return Response.status(403) // Forbidden
					.entity(Constants.EMPTY_XML_DOCUMENT).build();
		}

		return Response.status(200)
				// Ok
				.entity(uriInfo.getAbsolutePathBuilder().build().toString())
				.build();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.devariance.cone.logging.HasLogger#setLogger(org.slf4j.Logger)
	 */
	@Override
	public void setLogger(final Logger logger) {
		this.logger = logger;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.devariance.cone.rs.RestfulService#setResourceHandlerContext(com.
	 * devariance.cone.handler.ResourceHandlerContext)
	 */
	@Override
	public void setResourceHandlerContext(
			final ResourceHandlerContext resourceHandlerContext) {
		this.resourceHandlerContext = resourceHandlerContext;
	}
}
